﻿using System;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Sovacode.RubiksCube.Common.Command;
using Sovacode.RubiksCube.Common.ViewModel;

namespace Sovacode.RubiksCube.Common.Tests.CommandManager
{
    [TestClass]
    public class CommonCommandManagerTests
    {
        [TestMethod]
        public void AddCommand()
        {
            var viewModelTop = new ViewModelTop();

            viewModelTop.RegisterCommand("SampleCommand1", o => {});

            Assert.IsNotNull(viewModelTop.CommandManager.GetCommand("SampleCommand1"));
            Assert.IsTrue(viewModelTop.CommandsCount == 1);
            Assert.IsTrue(viewModelTop.ValidCommandsCount == 1);
            Assert.IsTrue(viewModelTop.InvalidCommandsCount == 0);
            Assert.IsTrue(viewModelTop.ValidCommands.Contains("SampleCommand1"));
            Assert.IsTrue(viewModelTop.AllCommands.Contains("SampleCommand1"));
            Assert.IsTrue(!viewModelTop.InvalidCommands.Contains("SampleCommand1"));

            viewModelTop.RegisterCommand<bool>("SampleCommand2", o => { });

            Assert.IsNotNull(viewModelTop.CommandManager.GetCommand("SampleCommand2"));
            Assert.IsTrue(viewModelTop.CommandsCount == 2);
            Assert.IsTrue(viewModelTop.ValidCommandsCount == 2);
            Assert.IsTrue(viewModelTop.InvalidCommandsCount == 0);
            Assert.IsTrue(viewModelTop.ValidCommands.Contains("SampleCommand2"));
            Assert.IsTrue(viewModelTop.AllCommands.Contains("SampleCommand2"));
            Assert.IsTrue(!viewModelTop.InvalidCommands.Contains("SampleCommand2"));

            viewModelTop.RegisterCommand("SampleCommand3", o => { }, p => true);

            Assert.IsNotNull(viewModelTop.CommandManager.GetCommand("SampleCommand3"));
            Assert.IsTrue(viewModelTop.CommandsCount == 3);
            Assert.IsTrue(viewModelTop.ValidCommandsCount == 3);
            Assert.IsTrue(viewModelTop.InvalidCommandsCount == 0);
            Assert.IsTrue(viewModelTop.ValidCommands.Contains("SampleCommand3"));
            Assert.IsTrue(viewModelTop.AllCommands.Contains("SampleCommand3"));
            Assert.IsTrue(!viewModelTop.InvalidCommands.Contains("SampleCommand3"));

            viewModelTop.RegisterCommand<bool>("SampleCommand4", o => { }, p => true);

            Assert.IsNotNull(viewModelTop.CommandManager.GetCommand("SampleCommand4"));
            Assert.IsTrue(viewModelTop.CommandsCount == 4);
            Assert.IsTrue(viewModelTop.ValidCommandsCount == 4);
            Assert.IsTrue(viewModelTop.InvalidCommandsCount == 0);
            Assert.IsTrue(viewModelTop.ValidCommands.Contains("SampleCommand4"));
            Assert.IsTrue(viewModelTop.AllCommands.Contains("SampleCommand4"));
            Assert.IsTrue(!viewModelTop.InvalidCommands.Contains("SampleCommand4"));

            viewModelTop.RegisterCommand("SampleCommand5", new RelayCommand<bool>(o => { }, p => true));

            Assert.IsNotNull(viewModelTop.CommandManager.GetCommand("SampleCommand5"));
            Assert.IsTrue(viewModelTop.CommandsCount == 5);
            Assert.IsTrue(viewModelTop.ValidCommandsCount == 5);
            Assert.IsTrue(viewModelTop.InvalidCommandsCount == 0);
            Assert.IsTrue(viewModelTop.ValidCommands.Contains("SampleCommand5"));
            Assert.IsTrue(viewModelTop.AllCommands.Contains("SampleCommand5"));
            Assert.IsTrue(!viewModelTop.InvalidCommands.Contains("SampleCommand5"));

        }

        [TestMethod]
        public void UnregisterCommand()
        {
            var viewModelTop = new ViewModelTop();

            viewModelTop.RegisterCommand("SampleCommand1", o => { });
            viewModelTop.RegisterCommand<bool>("SampleCommand2", o => { });
            viewModelTop.RegisterCommand("SampleCommand3", o => { }, p => true);
            viewModelTop.RegisterCommand<bool>("SampleCommand4", o => { }, p => true); 
            viewModelTop.RegisterCommand("SampleCommand5", new RelayCommand<bool>(o => { }, p => true));

            Assert.IsTrue(viewModelTop.CommandsCount == viewModelTop.ValidCommandsCount);
            Assert.IsTrue(viewModelTop.CommandsCount > 0);

            viewModelTop.CommandManager.Clear();

            Assert.IsTrue(viewModelTop.CommandsCount == viewModelTop.ValidCommandsCount);
            Assert.IsTrue(viewModelTop.CommandsCount == 0);
        }


        [TestMethod]
        public void BadCommands()
        {
            var viewModelTop = new ViewModelTop();

            Assert.IsNotNull(viewModelTop.CommandManager.GetCommand("BadCommand"));

            Assert.IsTrue(viewModelTop.InvalidCommandsCount == viewModelTop.CommandsCount);
            Assert.IsTrue(viewModelTop.InvalidCommandsCount == 1);

            Assert.IsNotNull(viewModelTop.CommandManager.GetCommand("BadCommand", false));

            Assert.IsTrue(viewModelTop.InvalidCommandsCount == viewModelTop.CommandsCount);
            Assert.IsTrue(viewModelTop.InvalidCommandsCount == 1);


            Assert.IsNull(viewModelTop.CommandManager.GetCommand("BadCommand2", false));

            Assert.IsTrue(viewModelTop.InvalidCommandsCount == viewModelTop.CommandsCount);
            Assert.IsTrue(viewModelTop.InvalidCommandsCount == 1);
        }


        [TestMethod]
        public void GetByIndexNameCommand()
        {
            var viewModelTop = new ViewModelTop();

            viewModelTop.RegisterCommand("SampleCommand1", o => { });
            viewModelTop.RegisterCommand<bool>("SampleCommand2", o => { });
            viewModelTop.RegisterCommand("SampleCommand3", o => { }, p => true);
            viewModelTop.RegisterCommand<bool>("SampleCommand4", o => { }, p => true);
            viewModelTop.RegisterCommand("SampleCommand5", new RelayCommand<bool>(o => { }, p => true));

            Assert.IsNotNull(viewModelTop["SampleCommand1"]);
            Assert.IsInstanceOfType(viewModelTop["SampleCommand1"], typeof(ICustomCommand));
            Assert.IsNotNull(viewModelTop["SampleCommand2"]);
            Assert.IsInstanceOfType(viewModelTop["SampleCommand2"], typeof(ICustomCommand));
            Assert.IsNotNull(viewModelTop["SampleCommand3"]);
            Assert.IsInstanceOfType(viewModelTop["SampleCommand3"], typeof(ICustomCommand));
            Assert.IsNotNull(viewModelTop["SampleCommand4"]);
            Assert.IsInstanceOfType(viewModelTop["SampleCommand4"], typeof(ICustomCommand));
            Assert.IsNotNull(viewModelTop["SampleCommand5"]);
            Assert.IsInstanceOfType(viewModelTop["SampleCommand5"], typeof(ICustomCommand));

            Assert.IsNotNull(viewModelTop["BadCommand"]);

            var customCommand = (viewModelTop["BadCommand"] as ICustomCommand);

            Assert.IsTrue(customCommand != null && customCommand.Type == CommandType.Error);
        }
    }
}
